package com.fc.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fc.dao.AddressMapper;
import com.fc.entity.Address;
import com.fc.entity.Employee;
import com.fc.entity.User;
import com.fc.entity.UserAddressRelation;
import com.fc.entity.input.AddressInput;
import com.fc.entity.input.DeleteBatchInput;
import com.fc.entity.output.AddressOutput;
import com.fc.entity.query.PageQuery;
import com.fc.entity.query.PageResult;
import com.fc.enums.DelFlagEnum;
import com.fc.exception.BusinessException;
import com.fc.service.AddressService;
import com.fc.service.UserAddressRelationService;
import com.fc.service.UserService;
import com.fc.service.baseService.impl.BaseServiceImpl;
import com.fc.service.baseService.impl.ThreadLocalService;
import com.fc.utils.ResultVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 地址表 服务实现类
 * </p>
 *
 * @author
 * @since 2024-11-04
 */
@Service
public class AddressServiceImpl extends BaseServiceImpl<AddressMapper, Address> implements AddressService {

    @Autowired
    private UserAddressRelationService userAddRelService;

    @Autowired
    private UserService userService;

    @Autowired
    private ThreadLocalService threadLocalService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean add(AddressInput input) {
        input.setId(null);
        Address address = BeanUtil.copyProperties(input, Address.class);
        Boolean b = savePre(address);
        if (!b) {
            throw new BusinessException(9999, "新增地址失败！！！");
        }
        UserAddressRelation relation = BeanUtil.copyProperties(input, UserAddressRelation.class);
        relation.setAddressId(address.getId());
        User user = userService.getOne(new LambdaQueryWrapper<User>()
                .eq(User::getUsername, threadLocalService.getThreadLocal())
                //都登陆了肯定存在，没必要加
                .eq(User::getDelFlag, DelFlagEnum.NORMAL));
        //todo 没写登录，threadLocal暂未数据，先写死
        //relation.setUserId(user.getId());
        relation.setUserId(1L);
        return userAddRelService.savePre(relation);
    }

    @Override
    public PageResult<AddressOutput> getPage(PageQuery query) {
        User user = userService.getOne(new LambdaQueryWrapper<User>()
                .eq(User::getUsername, threadLocalService.getThreadLocal())
                //都登陆了肯定存在，没必要加
                .eq(User::getDelFlag, DelFlagEnum.NORMAL));
        //限制查询数量
        LambdaQueryWrapper<UserAddressRelation> wrapper = new LambdaQueryWrapper<UserAddressRelation>()
                .eq(UserAddressRelation::getDelFlag, DelFlagEnum.NORMAL)
                //todo 没写登录，threadLocal暂未数据，先写死
                //.eq(UserAddressRelation::getUserId, user.getId())
                .eq(UserAddressRelation::getUserId, 1)
                .orderByAsc(UserAddressRelation::getAddressId);
        Page<UserAddressRelation> relPage = userAddRelService.page(Page.of(query.getPageNumber(), query.getPageSize()), wrapper);
        List<UserAddressRelation> list = relPage.getRecords();
        if (CollUtil.isEmpty(list)) {
            return new PageResult<>();
        }
        List<Long> addIds = list.stream().map(UserAddressRelation::getAddressId).toList();
        List<Address> addList = listByIds(addIds);

        List<AddressOutput> relList = BeanUtil.copyToList(addList, AddressOutput.class);
        Map<Long, UserAddressRelation> relMap = list.stream().collect(Collectors.toMap(UserAddressRelation::getAddressId, o -> o));
        relList.forEach(r -> {
            UserAddressRelation rel = relMap.getOrDefault(r.getId(), new UserAddressRelation());
            BeanUtil.copyProperties(rel, r, "id");
        });
        Page<AddressOutput> page = new Page<>(query.getPageNumber(), query.getPageSize(), relList.size());
        PageResult<AddressOutput> result = new PageResult<>();
        BeanUtil.copyProperties(page, result);
        result.setRecords(relList);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean renew(AddressInput input) {
        Address user = getById(input.getId());
        if (user == null || user.getDelFlag().equals(DelFlagEnum.DELETED)) {
            throw new BusinessException(9999, "用户不存在");
        }
        updateByIdPre(BeanUtil.copyProperties(input, Address.class));
        UserAddressRelation relation = userAddRelService.getOne(new LambdaQueryWrapper<UserAddressRelation>()
                .eq(UserAddressRelation::getDelFlag, DelFlagEnum.NORMAL)
                .eq(UserAddressRelation::getAddressId, input.getId()));
        BeanUtil.copyProperties(input, relation, "id");
        return userAddRelService.updateByIdPre(relation);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean del(DeleteBatchInput input) {
        List<Address> addrList = BeanUtil.copyToList(input.getIds(), Address.class);
        addrList.forEach(r -> r.setDelFlag(DelFlagEnum.DELETED));
        updateBatchByIdPre(addrList);

        List<UserAddressRelation> relationList = userAddRelService.list(new LambdaQueryWrapper<UserAddressRelation>()
                .eq(UserAddressRelation::getDelFlag, DelFlagEnum.NORMAL)
                .in(UserAddressRelation::getAddressId, input.getIds()));
        relationList.forEach(r -> r.setDelFlag(DelFlagEnum.DELETED));
        return userAddRelService.updateBatchByIdPre(relationList);
    }

    @Override
    public ResultVO<AddressOutput> detail(Long id) {
        Address addr = getById(id);
        if (addr == null || addr.getDelFlag().equals(DelFlagEnum.DELETED)) {
            throw new BusinessException(9999, "地址不存在");
        }
        UserAddressRelation relation = userAddRelService.getOne(new LambdaQueryWrapper<UserAddressRelation>()
                .eq(UserAddressRelation::getDelFlag, DelFlagEnum.NORMAL)
                .eq(UserAddressRelation::getAddressId, id));
        AddressOutput addressOutput = BeanUtil.copyProperties(addr, AddressOutput.class);
        BeanUtil.copyProperties(relation, addressOutput, "id");
        return ResultVO.success(addressOutput);
    }
}
